package org.enumerable.lambda.weaving;
import java.io.File;
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Enumeration;
/**
* This class can be used to attach the Enumerable.java agent to the currently running VM.
*
* It doesn't depend on any Enumerable.java classes and can serve as a template to write your own bootstrapping.
*/
public class LambdaAgentAttach {
/**
* Attempts to attach the Enumerable.java agent already present on the classpath to the running process.
* $JAVA_HOME/lib/tools.jar with com.sun.tools.attach.VirtualMachine must be present.
*/
public static void attachAgent() {
attachAgent(agentJar());
}
/**
* Attempts to attach the Enumerable.java jar to the running process.
* $JAVA_HOME/lib/tools.jar with com.sun.tools.attach.VirtualMachine must be present.
*/
public static void attachAgent(String pathToEnumerableJavaJar) {
try {
if (!toolsJar().isFile()) throw new IllegalStateException("Cannot find tools jar in " + System.getProperty("java.home" ));
Class<?> vmClass = classLoaderWithToolsJar().loadClass("com.sun.tools.attach.VirtualMachine");
Object vm = vmClass.getMethod("attach", String.class).invoke(null, pidOfRunningVM());
vmClass.getMethod("loadAgent", String.class).invoke(vm, pathToEnumerableJavaJar);
vmClass.getMethod("detach").invoke(vm);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private static String agentJar() {
Enumeration<URL> resources = potentialClasspathEntries();
while (resources.hasMoreElements()) {
URL url = resources.nextElement();
if ("jar".equals(url.getProtocol())) {
String file = url.getFile().split("!")[0];
if (file.startsWith("file:")) {
return file.replace("file:", "");
}
}
}
throw new IllegalStateException("Cannot find Enumerable.java on classpath");
}
private static Enumeration<URL> potentialClasspathEntries() {
try {
return LambdaAgentAttach.class.getClassLoader().getResources("org/enumerable/lambda/weaving/version.properties");
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private static URLClassLoader classLoaderWithToolsJar() throws MalformedURLException {
return new URLClassLoader(new URL[]{toolsJar().toURI().toURL()});
}
private static File toolsJar() {
return new File(System.getProperty("java.home" ), "../lib/tools.jar" );
}
private static String pidOfRunningVM() {
String nameOfRunningVM = ManagementFactory.getRuntimeMXBean().getName();
return nameOfRunningVM.substring(0, nameOfRunningVM.indexOf('@'));
}
}